<template>
  <div :class="['table-group', isCard && 'is-card']" :style="{ width: width }" v-loading="loading">
    <template v-if="$slots.header">
      <slot name="header"></slot>
    </template>
    <template v-else>
      <c-input width="100%" v-model="groupInput" placeholder="请输入关键字" />
    </template>

    <template v-if="$slots.default">
      <div class="table-group-list">
        <slot></slot>
      </div>
    </template>
    <el-scrollbar v-else>
      <ul class="table-group-list">
        <li
          v-for="(item, index) in list"
          :key="index"
          :class="[item[getOptions.id] == modelValue && 'is-active']"
          @click="handleGroupClick(item)"
        >
          <img
            class="is-img"
            v-if="getOptions.url && item[getOptions.url]"
            :src="item[getOptions.url]"
          />
          <span class="is-label">{{ item[getOptions.label] }}</span>
          <el-dropdown :hide-on-click="false" v-if="item[getOptions.id] != 0 && !isPreview">
            <el-icon class="is-more" @click.stop><MoreFilled /></el-icon>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item @click="handleEdite(item)">编辑</el-dropdown-item>
                <el-dropdown-item divided @click="handleDelete(item)">
                  <span class="is-error-text">删除</span>
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </li>
      </ul>
    </el-scrollbar>
    <el-button @click="handleCreate" v-if="!isPreview">{{ createBtnText }}</el-button>
  </div>
</template>

<script setup name="table-group">
import { computed, ref } from 'vue';
import { MoreFilled } from '@element-plus/icons-vue';

const emit = defineEmits(['on-change', 'on-create', 'on-edite', 'on-delete', 'update:modelValue']);

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: '',
  },
  width: {
    type: [String],
    default: '240px',
  },
  loading: {
    type: Boolean,
    default: false,
  },
  list: {
    type: Array,
    default: () => [],
  },
  options: {
    type: Object,
    default: () => {
      return {};
    },
  },
  createBtnText: {
    type: [String],
    default: '+ 新增分组',
  },
  isPreview: {
    type: Boolean,
    default: false,
  },
  isCard: {
    type: Boolean,
    default: true,
  },
});

const getOptions = computed(() => {
  const { id = 'id', label = 'label', url = 'url' } = props.options;
  return { id, label, url };
});

const groupInput = ref('');

const handleGroupClick = (item) => {
  emit('update:modelValue', item[getOptions.value.id]);
  emit('on-change', item);
};

const handleCreate = () => {
  emit('on-create');
};

const handleEdite = (item) => {
  emit('on-edite', item);
};

const handleDelete = (item) => {
  emit('on-delete', item);
};
</script>

<style lang="scss" scoped>
.table-group {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  margin-right: 6px;
  height: 100%;

  .is-card {
    padding: 14px 16px;
    box-sizing: border-box;
    @include card-box;
  }
}

.table-group-list {
  height: 100%;
  padding: 0;
  margin: 10px 0;

  .is-active {
    background-color: var(--el-menu-hover-bg-color) !important;
  }

  & > li {
    padding: 16px 12px 16px 14px;
    box-sizing: border-box;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: var(--el-text-color-primary);

    .is-img {
      width: 26px;
      height: 26px;
      border-radius: 4px;
      margin-right: 8px;
      object-fit: cover;
    }

    .is-label {
      flex: 1;
    }

    &:hover {
      background-color: var(--el-menu-hover-bg-color);
    }

    .is-more {
      color: var(--el-color-info);
      font-size: 12px;
      cursor: pointer;
      &:focus-visible {
        outline: none;
      }
    }
  }
}
</style>
